import * as THREE from "three"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { Water } from "three/examples/jsm/objects/Water";
import { Sky } from "three/examples/jsm/objects/Sky";
interface initGeometryOption {
    geometryOption: {
        name: string,
        sizes?: number[],
        option?: Array<any>,
        vertices?: Array<number>
    },
    materialOption: {
        name: string,
        color?: number | string,
        opacity?: number,
        transparent?: boolean,
        specular?: string,
        shininess?: number,
        size?: number,
        side?: any,
        wireframe?: any
    },
    objectName?: string,
    beforeAdd?: Function | null
}

class Box {
    private scene;
    private camera;
    private renderer;
    private container;
    private water;
    private sun;
    private sky;
    private pmremGenerator;
    private renderTarget;
    private cube;

    constructor() { }
    init(container) {
        this.container = container;

        // 设置渲染器
        this.setRender();
        // 初始化场景
        this.setScene();
        // 设置相机    
        this.setCamera();
        // 启动渲染
        this.render();
        // 动作监听
        this.addControl();
    }
    // 场景
    setScene() {
        this.scene = new THREE.Scene();

        //初始化模型
        this.initObjects();

        // //点光源
        // this.createLight("PointLight", "#ffffff", (point) => point.position.set(200, 300, 400));

        // // 点光源2  位置和point关于原点对称
        // this.createLight("PointLight", "#ffffff", (point) => point.position.set(-400, -200, -300));

        // //环境光
        // this.createLight("AmbientLight", "#444444");

        // 创建坐标系
        this.createAxis();
    }

    initObjects() {
        // water and sun
        this.sun = new THREE.Vector3(200, 20, 0);
        this.water = new Water(         //bufferGeometry、ShadeMaterial
            new THREE.PlaneGeometry(10000, 10000),
            {           //option
                waterNormals: new THREE.TextureLoader().load(
                    "/images/waternormals.jpg",
                    function (texture) {
                        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;//设置纹理循环平贴
                    }
                ),
                sunDirection: this.sun,
                sunColor: "#555",
                waterColor: "#001e0f"
            }
        );
        this.water.rotation.x = -Math.PI / 2;
        this.scene.add(this.water);

        //sky
        this.sky = new Sky();
        this.sky.scale.setScalar(10000);
        this.scene.add(this.sky);
        this.sky.material.uniforms["sunPosition"].value.copy(this.sun);

        // 物体的反射效果
        if (typeof this.renderTarget != "undefined") {
            this.renderTarget.dispose();
        }
        this.renderTarget = this.pmremGenerator.fromScene(this.sky);
        this.scene.environment = this.renderTarget.texture;

        //cube
        this.cube = new THREE.Mesh(
            new THREE.BoxGeometry(30, 30, 30),
            new THREE.MeshStandardMaterial()
        );
        this.scene.add(this.cube);
    }

    // 相机
    setCamera() {
        var width = this.container.offsetWidth; //窗口宽度
        var height = this.container.offsetHeight; //窗口高度
        var k = width / height; //窗口宽高比
        var s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
        //创建相机对象
        this.camera = new THREE.PerspectiveCamera(-s, width / height, 0.1, 1000);
        this.camera.position.set(0, 100, 0); //设置相机位置
        this.camera.up.set(0, 1, 0); //设置相机位置
        this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象)
    }
    // 渲染器
    setRender() {
        this.renderer = new THREE.WebGLRenderer();
        this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight);//设置渲染区域尺寸
        this.renderer.setClearColor("#000000", 1); //设置背景颜色
        this.renderer.toneMaooing = THREE.ACESFilmicToneMapping;
        this.container.appendChild(this.renderer.domElement); //body元素中插入canvas对象

        this.pmremGenerator = new THREE.PMREMGenerator(this.renderer);
    }
    // 渲染
    render() {
        const time = window.performance.now() * 0.001;
        this.cube.position.y = Math.sin(time) * 20 + 5;
        this.cube.rotation.x = time * 0.5;
        this.cube.rotation.z = time * 0.5;

        this.water.material.uniforms["time"].value += 1 / 60;
        this.renderer.render(this.scene, this.camera);
        //监听鼠标、键盘事件
        requestAnimationFrame(this.render.bind(this));
    }
    // 鼠标和键盘事件
    addControl() {
        var controls = new OrbitControls(this.camera, this.renderer.domElement);//创建控件对象
    }
    // 创建光源
    createLight(name, color, beforeAdd = null) {
        var point = new THREE[name](color);
        beforeAdd && beforeAdd(point);
        this.scene.add(point); //点光源添加到场景中
    }
    // 创建坐标系
    createAxis() {
        //辅助坐标系  参数250表示坐标系大小，可以根据场景大小去设置
        var axisHelper = new THREE.AxesHelper(250);
        this.scene.add(axisHelper);
    }
}

export default Box;